package com.example.fireassistant_server.service.impl;

import com.example.fireassistant_server.dto.Essential.EssentialCreateRequest;
import com.example.fireassistant_server.dto.Essential.EssentialDto;
import com.example.fireassistant_server.dto.Essential.EssentialSearchFilter;
import com.example.fireassistant_server.dto.Essential.EssentialUpdateRequest;
import com.example.fireassistant_server.entity.Company;
import com.example.fireassistant_server.entity.Essential;
import com.example.fireassistant_server.exception.BizException;
import com.example.fireassistant_server.exception.ExceptionType;
import com.example.fireassistant_server.mapper.EssentialMapper;
import com.example.fireassistant_server.repository.EssentialRepository;
import com.example.fireassistant_server.repository.FileRepository;
import com.example.fireassistant_server.repository.spec.EssentialSpecification;
import com.example.fireassistant_server.repository.spec.SearchCriteria;
import com.example.fireassistant_server.repository.spec.SearchOperation;
import com.example.fireassistant_server.repository.spec.UserSpecification;
import com.example.fireassistant_server.service.EssentialService;
import com.example.fireassistant_server.service.FileService;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class EssentialServiceImpl implements EssentialService {

    EssentialRepository essentialRepository;

    EssentialMapper essentialMapper;

    FileService fileService;

    private EntityManager entityManager;

    @Override
    public EssentialDto create(EssentialCreateRequest essentialCreateRequest) {
        Essential essential = essentialMapper.createEntity(essentialCreateRequest);
        return essentialMapper.toDto(essentialRepository.save(essential));
    }

    @Override
    public EssentialDto update(String id, EssentialUpdateRequest essentialUpdateRequest) {
        Optional<Essential> essential = essentialRepository.findById(id);
        if (!essential.isPresent()) {
            throw new BizException(ExceptionType.ESSENTIAL_NOT_FOUND);
        }
        if (essentialUpdateRequest.getKeyword() != null){
            essential.get().setKeyword(essentialUpdateRequest.getKeyword());
        }

        if (essentialUpdateRequest.getContent() !=null ){
            essential.get().setContent(essentialUpdateRequest.getContent());
        }
        if (essentialUpdateRequest.getFileId() != null){
            essential.get().setFile(fileService.getById(essentialUpdateRequest.getFileId()));
        }

        if (essentialUpdateRequest.getTypical()!= null){
            essential.get().setTypical(essentialUpdateRequest.getTypical());
        }
        essentialRepository.flush();
        return essentialMapper.toDto(essentialRepository.save(essential.get()));
    }

    @Override
    public List<EssentialDto> findByKeywordLike(String keyword) {
        return essentialRepository.findByKeywordLike(keyword).stream().map(essentialMapper::toDto).collect(Collectors.toList());
    }

    @Override
    public EssentialDto getById(String id) {
        Optional<Essential> essential = essentialRepository.findById(id);
        if (!essential.isPresent()) {
            throw new BizException(ExceptionType.ESSENTIAL_NOT_FOUND);
        }
        return essentialMapper.toDto(essential.get());
    }


    @Override
    public Page<EssentialDto> searchAll(EssentialSearchFilter essentialSearchFilter) {
        EssentialSpecification specs = new EssentialSpecification();
        if (essentialSearchFilter.getKeyword() !=null && !Objects.equals(essentialSearchFilter.getKeyword(), "")){
            specs.add(new SearchCriteria("keyword",essentialSearchFilter.getKeyword(),SearchOperation.MATCH));
        }
        if (essentialSearchFilter.getContent() !=null && !Objects.equals(essentialSearchFilter.getContent(), "")){
            specs.add(new SearchCriteria("content",essentialSearchFilter.getContent(),SearchOperation.MATCH));
        }
        return essentialRepository.findAll(specs, essentialSearchFilter.toPageable()).map(essentialMapper::toDto);
    }

    @Override
    @Transactional
    public void deleteById(String id) {
        Optional<Essential> essential = essentialRepository.findById(id);
        if (!essential.isPresent()) {
            throw new BizException(ExceptionType.ESSENTIAL_NOT_FOUND);
        }
        essentialRepository.deleteById(id);
        if (essential.get().getFile()!=null){
            fileService.deleteById(essential.get().getFile().getId());
        }
    }



    @Autowired
    public void setEssentialRepository(EssentialRepository essentialRepository) {
        this.essentialRepository = essentialRepository;
    }

    @Autowired
    public void setEssentialMapper(EssentialMapper essentialMapper) {
        this.essentialMapper = essentialMapper;
    }

    @Autowired
    public void setFileService(FileService fileService) {
        this.fileService = fileService;
    }

    @Autowired
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
}
